/**
 * 
 */
package com.googlecode.xcarve.demoservice;

import java.lang.reflect.Method;
import java.util.Date;

import org.junit.Test;
import org.springframework.cglib.reflect.FastClass;
import org.springframework.cglib.reflect.FastMethod;

import com.googlecode.xcarve.fastmethod.Getter;
import com.googlecode.xcarve.fastmethod.Invokers;
import com.googlecode.xcarve.fastmethod.Setter;
import com.googlecode.xcarve.fastmethod.Invokers.Invoker;
import com.googlecode.xcarve.object.Demo;
import com.googlecode.xcarve.wrapper.ServiceWrapper;

/**
 * @author xinyun.d
 * 2014年10月2日
 */
public class WrapperBenchMark {
	public static void main(String[] args)throws Throwable  {
		DemoService service = new DemoServiceImpl();
		ServiceWrapper wrapper = ServiceWrapper.getWrapper(DemoService.class);
		Object obj = wrapper.invokeMethod(service, "sayHello", new Class<?>[] {}, new Object[]{});
		System.out.println(obj);
		Method method = service.getClass().getMethod("sayHello", new Class<?>[] {});
		long start = System.currentTimeMillis();
//		for(int i=0;i<1000000;i++){ //12s
//			wrapper = Wrapper.getWrapper(DemoService.class);
//			Object obj = wrapper.invokeMethod(service, "sayHello", new Class<?>[] {}, new Object[]{});
//			System.out.println(obj);
//		}
//		for(int i=0;i<1000000;i++){ //12s
//			System.out.println(service.sayHello());
//		}
		
		for(int i=0;i<1000000;i++){
			System.out.println(method.invoke(service, null));
		}
		
		long end = System.currentTimeMillis();
		System.out.println((end-start)/1000);
		
	
		
	}
	
	@Test  
	public void testInvoker() {  
	    try {  
	    	Demo param = new Demo();
	    	param.setId(1);
	    	param.setName("2");
	    	param.setTaskId(898989L);
	    	param.setTime(System.currentTimeMillis());
	    	DemoService demo = new DemoServiceImpl();
	        Method getMethod = DemoService.class.getMethod("sendDemo", Demo.class);  
	        getMethod.setAccessible(true);  
	        Invoker get = Invokers.newInvoker(getMethod);  
	        FastClass fastClass = FastClass.create(DemoService.class);  
	        FastMethod fastGetMethod = fastClass.getMethod(getMethod);  
	        long start = System.currentTimeMillis();
	        for (int i = 0; i < 100000000; i++) {  
	        	fastGetMethod.invoke(demo, new Object[] {param});
	        }  
//	       
	        System.out.println("fast调用耗时："+ (System.currentTimeMillis() - start));
	        System.out.println(get.invoke(demo, new Object[] {param}));
	        Setter demoinvoker = Invokers.newInvoker(Setter.class, DemoServiceImpl.class, "sendDemo", new Class<?>[]{Demo.class}, Demo.class);
	        demoinvoker.set(demo, param);
	        System.out.println(param);
	        start = System.currentTimeMillis();
	        for (int i = 0; i < 100000000; i++) {  
//	            get.invoke(demo, new Object[] {param});
	        	demoinvoker.set(demo, param);
	        }  
	        
	        System.out.println("Invoker调用耗时："+ (System.currentTimeMillis() - start));
	      
	        System.gc();
	    	DemoService service = new DemoServiceImpl();
			ServiceWrapper wrapper = ServiceWrapper.getWrapper(DemoService.class);
			Object obj = wrapper.invokeMethod(service, "sendDemo", new Class<?>[] {Demo.class}, new Object[]{param});
			System.out.println(obj);
			System.gc();
			 start = System.currentTimeMillis();
			for(int i=0;i< 100000000;i++){
				obj = wrapper.invokeMethod(service, "sendDemo", new Class<?>[] {Demo.class}, new Object[]{param});
			}
	        System.out.println("wrapper调用耗时：" + (System.currentTimeMillis() - start)+ "ms");  
	        System.gc();
	        start = System.currentTimeMillis();  
	        for (int i = 0; i < 100000000; i++) {  
	            getMethod.invoke(demo, new Object[] {param});  
	        }  
	        System.out.println("JDK反射调用耗时：" + (System.currentTimeMillis() - start) + "ms");  
 
	    } catch (Exception e) {  
	        e.printStackTrace();  
	    }  
	  
	}  
	
	@Test
	public void invoker() {  
	    try {  
	        Date date = new Date();  
	        Method getMethod = Date.class.getMethod("getTime");  
	        getMethod.setAccessible(true);  
	        Method setMethod = Date.class.getMethod("setTime", Long.TYPE);  
	        setMethod.setAccessible(true);  
	        Invoker get = Invokers.newInvoker(getMethod);  
	        Invoker set = Invokers.newInvoker(setMethod);  
	        FastClass fastClass = FastClass.create(Date.class);  
	        FastMethod fastGetMethod = fastClass.getMethod(getMethod);  
	        FastMethod fastSetMethod = fastClass.getMethod(setMethod);  
	  
	        System.out.println(get.invoke(date, new Object[] {}));  
	        set.invoke(date, new Object[] { 333333L });  
	        System.out.println(get.invoke(date, new Object[] {}));  
	        long t0 = System.currentTimeMillis();  
	        for (int i = 0; i < 100000000; i++) {  
	            get.invoke(date, new Object[] {});  
//	            set.invoke(date, new Object[] { 333333L });  
	        }  
	        long t1 = System.currentTimeMillis();  
	        System.out.println("Invoker调用耗时：" + (t1 - t0) + "ms");  
	        
	        ServiceWrapper wrapper = ServiceWrapper.getWrapper(Date.class);
			Object obj = wrapper.invokeMethod(date, "getTime", new Class<?>[] {}, new Object[]{});
			System.out.println(obj);
			 t1 = System.currentTimeMillis();  
		    for (int i = 0; i < 100000000; i++) {  
		    	wrapper.invokeMethod(date, "getTime", new Class<?>[] {}, new Object[]{});
//		    	wrapper.invokeMethod(date, "setTime", new Class<?>[] {Long.class}, new Object[]{5555555});
	        }  
		    long t2 = System.currentTimeMillis();  
	        System.out.println("wrapper反射调用耗时：" + (t2 - t1) + "ms");
	        
	        t1 = System.currentTimeMillis();  
	        for (int i = 0; i < 100000000; i++) {  
	            getMethod.invoke(date, new Object[] {});  
	            setMethod.invoke(date, new Object[] { 333333L });  
	        }  
	        t2 = System.currentTimeMillis();  
	        System.out.println("JDK反射调用耗时：" + (t2 - t1) + "ms");  
	        t2 = System.currentTimeMillis();  
	        for (int i = 0; i < 100000000; i++) {  
	            fastGetMethod.invoke(date, new Object[] {});  
	            fastSetMethod.invoke(date, new Object[] { 333333L });  
	        }  
	        long t3 = System.currentTimeMillis();  
	        System.out.println("CGLIB反射调用耗时：" + (t3 - t2) + "ms");  
	    } catch (Exception e) {  
	        e.printStackTrace();  
	    }  
	  
	}  
}
